
#include "stdafx.h"
#ifndef _WEBKIT_NEW

#include "FlashSecuritySocket.h"
#include "PolicyDelegate.h"
#include "HookFunc.h"

LPCSTR crossdomain_Request = "<policy-file-request/>";
LPCSTR crossdomainXML =
	"<?xml version=\"1.0\" ?>\n"
	"<cross-domain-policy>\n"
	"<site-control permitted-cross-domain-policies = \"all\" />\n"
	"<allow-access-from domain=\"*\" to-ports=\"*\" secure=\"false\" />\n"
	"<allow-http-request-headers-from domain=\"*\" headers=\"*\" />\n"
	"</cross-domain-policy>\n";

CFlashSecuritySocket::CFlashSecuritySocket(CPolicyDelegate *caller)
	:m_Caller(caller)
{
}

CFlashSecuritySocket::~CFlashSecuritySocket()
{
}

LPVOID CFlashSecuritySocket::initClientThread()
{
	CSecurityThread* pThread = (CSecurityThread*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, m_ClientNum*sizeof(CSecurityThread));
	if (pThread) for (intptr_t i = 0; i < m_ClientNum; i++) pThread[i].init(m_Caller);
	return pThread;
}

void CFlashSecuritySocket::doneClientThread()
{
	CSecurityThread *pThread = (CSecurityThread *)pClientThread;
	for (intptr_t i = 0; i < m_ClientNum; i++, pThread++) pThread->stopThread(true);
}

bool CFlashSecuritySocket::startClientThread(SOCKET cltSock)
{
	return pClientThread ? ((CSecurityThread *)pClientThread)->startThread(cltSock) : false;
}



void CSecurityThread::init(CPolicyDelegate *caller)
{
	hCltThread = nullptr; cltSock = INVALID_SOCKET; m_Caller = caller;
}

DWORD WINAPI StartThread_SecurityClient(LPVOID p)
{
	CSecurityThread *pCaller = (CSecurityThread*)p; if (!pCaller) return -1;
	pCaller->ProcCltThread();
	return 0;
}
bool CSecurityThread::startThread(SOCKET sock)
{
	stopThread(true);
	cltSock = sock;
	hCltThread = CreateThread(NULL, 0, StartThread_SecurityClient, this, 0, NULL);
	return hCltThread != nullptr;
}

void CSecurityThread::stopThread(bool wait)
{
	if (!threadRunning()) return;
	stopCltThread = true;
	if (threadRunning() && wait) while (threadRunning()) Sleep(10);
}

bool CSecurityThread::threadRunning()
{
	return CheckThread(hCltThread);
}

void CSecurityThread::ProcCltThread()
{
	char recvBuf[4096];
	for (stopCltThread = false; cltSock != INVALID_SOCKET && !stopCltThread; Sleep(10))
	{
		intptr_t r = FUNC_testSock(cltSock, true); if (r == 0) continue;
		if (r > 0)
		{
			intptr_t ln = gHook.s_pfnrecv(cltSock, recvBuf, sizeof(recvBuf), 0); if (ln <= 0) break;
			if (_strcmpi(recvBuf, crossdomain_Request)) continue;
			for (intptr_t i = 0; i < 100; i++, Sleep(10))
			{
				r = FUNC_testSock(cltSock, false); if (r == 0) continue;
				if (r > 0)
				{
					if (gHook.s_pfnsend(cltSock, crossdomainXML, (int)strlen(crossdomainXML) + 1, 0) > 0)
						m_Caller->BeginBid();
				}
				break;
			}
		}
		break;
	}
	if (cltSock != INVALID_SOCKET) {
		FUNC_shutdown(cltSock, SD_BOTH); FUNC_closesocket(cltSock); cltSock = INVALID_SOCKET;
	}
}

#endif	//_WEBKIT_NEW
